package com.qwiki.text;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Corresponds to an external link in wikipedia.
 * 
 * @author xgu
 * 
 * @since May 30, 2012
 */
public class InternalLinkNode extends Node
{
  List<Node> children;
  String category;
  String displayText = "";
  String entity = "";

  @Override
  public boolean isCategory()
  {
    return category != null;
  }

  @Override
  public String getCategory()
  {
    if (category == null)
      return null;
    if (category.contains("\n"))
    {
      category = category.replaceAll("\n", "");
    }
    if (category.contains("\r"))
    {
      category = category.replaceAll("\r", "");
    }
    if (category.contains("_"))
    {
      category = category.replaceAll("_", " ");
    }
    if (category.contains("&nbsp;"))
    {
      category = category.replaceAll("&nbsp;", " ");
    }
    return category;
  }

  public String getEntity()
  {
    int hash = -1;
    if ((hash = entity.indexOf('#')) > 0)
    {
      entity = entity.substring(0, hash);
    }
    if (entity.contains("_"))
    {
      entity = entity.replaceAll("_", " ");
    }
    if (entity.contains("&nbsp;"))
    {
      entity = entity.replaceAll("&nbsp;", " ");
    }
    return entity;
  }

  @Override
  public String getText()
  {
    if (displayText.contains("_"))
    {
      displayText = displayText.replaceAll("_", " ");
    }
    if (displayText.contains("&nbsp;"))
    {
      displayText = displayText.replaceAll("&nbsp;", " ");
    }
    return displayText;
  }

  @Override
  public List<Node> getChildren()
  {
    return Collections.EMPTY_LIST;
  }

  @Override
  public boolean parse(char[] buffer, int start)
  {
    boolean parse = parseInternal(buffer, start);
    if (parse)
    {
      String orig = getOriginalText();
      if (orig.startsWith("[[Category:"))
      {
        // recognize Category constructs
        int bar = orig.indexOf('|');
        if (bar < 0)
        {
          bar = orig.length() - 2;
        }
        category = orig.substring(11, bar);
        TextNode textnode = new TextNode();
        textnode.parse(category.toCharArray(), 0);
        category = textnode.getText().trim();
        // categories.add(category);
      } else if (orig.indexOf(':') < 0)
      {
        // no special prefix
        int bar = orig.indexOf('|');
        if (bar < 0)
        {
          // no bar
          displayText = orig.substring(2, orig.length() - 2).trim();
          entity = displayText;
        } else
        {
          // with bar
          int endptr = orig.length() - 2;
          displayText = orig.substring(Math.min(bar + 1, endptr), endptr).trim();
          entity = orig.substring(2, bar);
          if (displayText.contains("{"))
          {
            // ignore if it has special characters
            displayText = "";
          }
        }
        // ///////////////////////
      } else
      {
        int firstcolon = orig.indexOf(':');
        int secondcolon = orig.indexOf(':', firstcolon + 1);
        int place = Math.max(firstcolon, secondcolon);
        if (place >= 0)
        {
          String prefix = orig.substring(0, place + 1);
        }
      }
    }
    return parse;
  }

  private boolean parseInternal(char[] buffer, int start)
  {
    children = new ArrayList<Node>();
    this.start = start;
    this.buffer = buffer;
    if (match(buffer, start, "[["))
    {
      int i = start + 2; // add the length of the delimiter [
      InternalLinkNode node = new InternalLinkNode();
      while (i < buffer.length)
      {
        // parse nested InternalLinkNode
        if (node.parse(buffer, i))
        {
          i += node.getLength();
          node.parsed = false;
          continue;
        }
        // parse end of InternalLinkNode
        if (match(buffer, i, "]]"))
        {
          end = i + 2; // add the length of the delimiter ]
          parsed = true;
          return true;
        }
        i++;
      }
    }
    return false;
  }

}
